package page

import (
	"gorm.io/gorm"
	"math"
)

type PageInfo struct {
	PageNum  int64 `json:"pageIndex"` // 页码
	PageSize int64 `json:"pageSize"`  // 每页数
	Total    int64 `json:"total"`     // 总数
	Pages    int64 `json:"pages"`     // 总页数
}

type Model[T any] struct {
	PageInfo *PageInfo
	List     []*T
}

// 各种查询条件先在query设置好后再放进来
func GetResult[T any](db *gorm.DB, pageNum int64, pageSize int64) (res *Model[T], e error) {
	model := &Model[T]{
		PageInfo: &PageInfo{},
		List:     []*T{},
	}
	model.PageInfo.PageNum = pageNum
	model.PageInfo.PageSize = pageSize
	err := db.Count(&model.PageInfo.Total).Error
	if err != nil {
		return model, err
	}
	if model.PageInfo.Total == 0 {
		model.List = []*T{}
		return model, err
	}
	e = db.Scopes(Paginate(model)).Find(&model.List).Error
	return model, e
}

// 各种查询条件先在query设置好后再放进来
func GetResultWithModel[T any](db *gorm.DB, pageNum int64, pageSize int64, t any) (e error) {
	page := &Model[T]{}
	page.PageInfo.PageNum = pageNum
	page.PageInfo.PageSize = pageSize
	db.Count(&page.PageInfo.Total)
	if page.PageInfo.Total == 0 {
		page.List = []*T{}
		return
	}
	e = db.Model(&t).Scopes(Paginate(page)).Find(&page.List).Error
	return
}

func Paginate[T any](page *Model[T]) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if page.PageInfo.PageNum <= 0 {
			page.PageInfo.PageNum = 1
		}
		switch {
		case page.PageInfo.PageSize > 10000:
			page.PageInfo.PageSize = 10000 // 限制一下分页大小
		case page.PageInfo.PageSize <= 0:
			page.PageInfo.PageSize = 10
		}
		// 使用浮点数除法，然后向上取整
		page.PageInfo.Pages = int64(math.Ceil(float64(page.PageInfo.Total) / float64(page.PageInfo.PageSize)))
		p := page.PageInfo.PageNum
		if page.PageInfo.PageNum > page.PageInfo.Pages {
			p = page.PageInfo.Pages
		}
		size := page.PageInfo.PageSize
		offset := int((p - 1) * size)
		return db.Offset(offset).Limit(int(size))
	}
}
